/**
 * @BitmapMovie.as
 *
 * @author sodaChen mail:asframe@qq.com
 * @version 1.0
 * <br>Copyright (C), 2012 ASFrame.com
 * <br>This program is protected by copyright laws.
 * <br>Program Name:ASFrame
 * <br>Date:2013-6-19
 */
package com.asframe.display.bmp
{
	import com.asframe.display.data.FrameData;
	import com.asframe.mgr.TimeMgr;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Point;

	/**
	 * 利用Bitmap实现的动画.这里是纯粹的一帧帧播放。不做其他的任何处理。相当于播放器
	 * 这个类已经废弃
	 * @author sodaChen
	 * #Date:2013-6-19
	 */
	public class BitmapMovie extends Bitmap
	{
		/** 附加的额外数据 **/
		public var extra				:*;
		/** 动画播放帧频(播放速度，单位是毫秒) **/
		public var frameRate			:int = 33;
		/** 当前动画是否循环播放 **/
		public var isLoop				:Boolean;
		/** 是否正在播放 **/
		public var isPlaying			:Boolean;
		/** 播放结束的回调函数 **/
		public var playComplete			:Function;

		/** 开始播放的帧数(0开始) **/
		protected var mStart			:int;
		/** 播放的帧数 **/
		protected var mEnd				:int;
		/** 最大帧数 **/
		protected var mTotalFrame		:int;
		/** 当前帧数 **/
		protected var mCurrentFrame		:int;
		/** 当前播放动画的图像数组数据 **/
		protected var mBitmapDatas		:Vector.<BitmapData>;
		/** 当前播放动画的帧数组数据 **/
		protected var mFrames			:Vector.<FrameData>;
		protected var localtionX		:int;
		protected var localtionY		:int;

		public function BitmapMovie(pixelSnapping:String="auto", smoothing:Boolean=false)
		{
			super(null, pixelSnapping, smoothing);
		}
		/**
		 * 改变图像动画的xy坐标。注意，因为本身有可能会自动设置xy坐标，所以改变改动整体坐标，必须调用这个方法来进行设置
		 * (其实是可以通过增加容器的方式来保证BitmapMovie不被自身改变坐标系)
		 * @param x
		 * @param y
		 *
		 */
		public function setLocation(x:int,y:int):void
		{
			localtionX = x;
			localtionY = y;
		}
		public function getLocation():Point
		{
			return new Point(localtionX,localtionY);
		}
		/**
		 * 改变动画的帧频
		 * @param _frameRate 新的帧频（毫秒）
		 *
		 */
		public function changeFrameRate(_frameRate:int):void
		{
			this.frameRate = _frameRate;
			if(isPlaying)
			{
				TimeMgr.removeDelay(tick);
				TimeMgr.addDelay(_frameRate,tick);
			}
		}
		/**
		 * 渲染当前帧数的图像信息
		 */
		public function render():void
		{
			bitmapData = mBitmapDatas[mCurrentFrame];
			//更新位置
			if(mFrames != null)
			{
				x = mFrames[mCurrentFrame].x + localtionX;
				y = mFrames[mCurrentFrame].y + localtionY;
				//这里还需要检测当前帧是否有数据，有的话，还需要处理
			}
		}
		/**
		 * 获取动画的当前帧(只读)
		 * @return
		 */
		public function get currentFrame():int
		{
			return mCurrentFrame + 1;
		}
		/**
		 * 返回动画的最大帧数(只读)
		 * @return
		 */
		public function get totalFrame():int
		{
			return mTotalFrame;
		}
		/**
		 * 设置图像动画序列的图像数据组.默认显示第一帧
		 * @param bitmapDatas
		 *
		 */
		public function setBitmapDatas(bitmapDatas:Vector.<BitmapData>):void
		{
			this.mBitmapDatas = bitmapDatas;
			mTotalFrame = bitmapDatas.length;
			mCurrentFrame = 0;
			bitmapData = mBitmapDatas[mCurrentFrame];
		}
		/**
		 * 设置图像动画序列的帧图像数据组。包含了每帧动画的范围和偏移数据.默认显示第一帧
		 * @param frames 动画帧数据的数组
		 * @param bitmapDatas 每一帧的图像数，和frames的数量保持一样，BitmapData也一样。
		 *        为空时，则会自动根据frames生成一份
		 */
		public function setFrames(frames:Vector.<FrameData>,bitmapDatas:Vector.<BitmapData> = null):void
		{
			this.mFrames = frames;
			this.mBitmapDatas = bitmapDatas;
			mTotalFrame = mFrames.length;
			if(bitmapDatas == null)
			{
				mBitmapDatas = new Vector.<BitmapData>();
				for (var i:int = 0; i < mTotalFrame; i++)
				{
					mBitmapDatas.push(mFrames[i].bitmapData);
				}
			}
			mCurrentFrame = 0;
			render();
		}
		/**
		 * 播放Bitmap动画
		 * @param isLoop 是否循环播放，为true时不能具备callBack函数
		 * @param callBack 结束帧数时的回调函数，注意这个有参数时isLoop必须为false
		 */
		public function play(isLoop:Boolean = true,playComplete:Function = null):void
		{
			if(isLoop && playComplete != null)
				throw new Error("不能循环的时候具备playComplete参数");

			if(playComplete != null)
			{
				this.playComplete = playComplete;
			}
			this.isLoop = isLoop;
			//还没播放
			if(!isPlaying)
			{
				//添加到心跳列表中
				TimeMgr.addDelay(frameRate,tick);
				isPlaying = true;
			}
			render();
		}
		/**
		 * 停止播放动画
		 */
		public function stop():void
		{
			if(isPlaying)
			{
				TimeMgr.removeDelay(tick);
				isPlaying = false;
			}
		}
		/**
		 * 跳转到指定的帧数，并且播放动画
		 * @param start 需要跳转的帧数
		 * @param end 结束帧数，默认是动画的最后一帧
		 * @param isLoop 是否循环
		 * @param playComplete 播放完一次的回调函数
		 *
		 */
		public function gotoAndPlay(start:int, end:int = -1,isLoop:Boolean = true,playComplete:Function = null):void
		{
			if(isLoop && playComplete != null)
				throw new Error("不能循环的时候具备playComplete参数");

			this.mStart = start - 1;
			this.mCurrentFrame = mStart;
			if(end != -1)
				this.mEnd = end;

			play(isLoop,playComplete);
		}
		public function gotoAndStop(stopFrame:int = -1):void
		{
			stop();
			//渲染当前帧
			if(stopFrame == -1)
				mCurrentFrame = mEnd - 1;
			else
				mCurrentFrame = stopFrame - 1;

			render();
		}
		public function tick():void
		{
			mCurrentFrame++;
			if(mCurrentFrame >= mEnd)
			{
				if(isLoop)
				{
					mCurrentFrame = mStart;
				}
				else
				{
					//没有循环，则表示已经播放完了
					stop();
				}
				//回调
				if(playComplete != null)
				{
					//这里这样设计的原因，是有可能playComplete回调的时候，还会再次调用play之类的方法进行重新设置playComplete
					var temp:Function = playComplete;
					playComplete = null;
					if(temp.length == 1)
						temp(this);
					else
						temp();
				}
				return ;
			}
			render();
		}
	}
}
